﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Daphne.Modularity.UI;

namespace Daphne.Modularity.Storage
{
    /// <summary>
    /// Storage service class
    /// </summary>
    internal class StorageService: IStorageService
    {
        private const string _suffixVM = "VM";

        /// <summary>
        /// Clients consuming the service of this class
        /// </summary>
        private List<ISaveRestore> _clients;

        /// <summary>
        /// The main configuration container dictionary
        /// </summary>
        private Dictionary<string, object> _configuration;

        /// <summary>
        /// Constructor
        /// </summary>
        public StorageService()
        {
            // init variables
            _clients = new List<ISaveRestore>();
            _configuration = new Dictionary<string, object>();
        }

        /// <summary>
        /// Loads the configuration
        /// TO-DO: implement after reading async communication
        /// TO-DO: use LocalStorage
        /// </summary>
        public void LoadConfig()
        {
        }

        /// <summary>
        /// Saves the configuration
        /// TO-DO: use LocalStorage
        /// </summary>
        public void SaveConfig()
        {
        }

        /// <summary>
        /// Sends loaded configuration to clients
        /// </summary>
        private void NotifyClientsToLoad()
        {
            // iterate clients
            foreach(var client in _clients)
            {
                // check, if configuration contains client's state
                object objStorage;
                if (_configuration.TryGetValue(client.Key, out objStorage) == false)
                    continue;

                // check type
                if(objStorage is ClientStorage)
                {
                    client.LoadState(objStorage as ClientStorage);
                }
            }
        }

        
        /// <summary>
        /// Requests clients to save their configuration
        /// </summary>
        private void NotifyClientsToSave()
        {
            // iterate clients
            foreach(var client in _clients)
            {
                // call to save
                ClientStorage storage = new ClientStorage();
                client.SaveState(storage);

                _configuration[client.Key] = storage;
            }
        }

        /// <summary>
        /// Registers the client class
        /// </summary>
        public void Register(ISaveRestore client)
        {
            if (_clients.Contains(client) == false)
                _clients.Add(client);
        }

        /// <summary>
        /// Saves the page's state
        /// </summary>
        public void SetPageState(string key, PageState pageState, ClientStorage viewModelState)
        {
            _configuration[key] = pageState;
            if (viewModelState != null)
                _configuration[key + _suffixVM] = viewModelState;
        }

        /// <summary>
        /// Returns the pages state
        /// </summary>
        public void GetPageState(string key, out PageState pageState, out ClientStorage viewModelState)
        {
            // set null values
            pageState = null;
            viewModelState = null;

            // try to get page configuration
            object objState;
            if(_configuration.TryGetValue(key, out objState))
            {
                if (objState is PageState)
                    pageState = objState as PageState;
            }

            // try to get viewmodel configuration
            if(_configuration.TryGetValue(key + _suffixVM, out objState))
            {
                if (objState is ClientStorage)
                    viewModelState = objState as ClientStorage;
            }
        }
    }
}
